package control;

import databasehandling.HandlerFactory;
import databasehandling.KasseHandler;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import model.BilletSalg;
import model.EventSalg;
import model.Kasse;
import model.Salg;
import model.VareSalg;


public class KasseController {

    private static KasseController instance;
    private final KasseHandler kasseHandler;
    private Kasse aktivKasse;

    /**
     * Opretter ny KasseController
     */
    private KasseController() {
        aktivKasse = null;
        kasseHandler = HandlerFactory.getInstance().getKasseHandler();
    }

    public static KasseController getInstance() {
        if (instance == null) {
            instance = new KasseController();
        }
        return instance;
    }

    /**
     * Sætter variablen, 'aktivKasse' til den kasse som passer på dags dato.
     *
     * @return true hvis kasse-objektet allerede eksisterede i databasen false
     * hvis kasse objektet skal oprettes. Her henvises der til at man kalder
     * 'opretNyKasseForIdag' i KasseControlleren som selv vil sørge for, at aktivKasse
     * bliver sat.
     * @throws SQLException hvis getKasseVedDagsDato fejler.
     * @throws ParseException hvis der opstår en parsing-fejl i kasseHandleren.
     * metode: getKasseVedDato
     */
    public boolean setDagsKasse() throws SQLException, ParseException {
        boolean succes = false;
        aktivKasse = kasseHandler.getKasseVedDato(Calendar.getInstance());
        if (aktivKasse != null) {
            succes = true;
        }
        return succes;
    }

    /**
     * Laver et nyt kasseObjekt og lægger det i databasen. Det er stærkt
     * anbefalet at man kører metoden setDagsKasse inden. Hvis denne returnerer
     * false, kan man køre denne.
     *
     * @param startBeholdningDKK
     * @param startBeholdningEURO
     * @throws SQLException hvis forbindelsen til databasen er mistet, eller
     * hvis det ikke var muligt at indsætte en record i KasseTabellen i DB.
     * @throws java.text.ParseException
     */
    public void opretNyKasseForIdag(int startBeholdningDKK, int startBeholdningEURO) throws SQLException, ParseException {
        kasseHandler.opretKasse(new Kasse(Calendar.getInstance(), startBeholdningDKK, startBeholdningEURO));
        setDagsKasse();
    }

    public Kasse getAktivKasse() {
        return aktivKasse;
    }

    /**
     * Metoden returnerer det samlede salgsbeløb i Danske Kroner for det kasse objekt 
     * metoden er kaldt med.
     * 
     * @param kasse Kasse
     * @param dankort boolean
     * @return
     * @throws SQLException
     * @throws ParseException 
     */
    public int totalSalgDKKVedKasse(Kasse kasse, boolean dankort) throws SQLException, ParseException {
        int beholdningDKK = 0;
        ArrayList<Salg> salgsListe = kasseHandler.hentAlleSalgVedKasse(kasse);
        for (int i = 0; i < salgsListe.size(); i++) {
            Salg salg = salgsListe.get(i);
            if (dankort == salg.isDankort()) {
                if (salg.isValutaDKK()) {
                    beholdningDKK = beholdningDKK + salg.getTotalBeløb();
                }
            }
        }

        return beholdningDKK;
    }

    /**
     * Metoden returnerer det samlede salgsbeløb i EURO for det kasse objekt 
     * metoden er kaldt med.
     * @param kasse Kasse
     * @param dankort boolean
     * @return
     * @throws SQLException
     * @throws ParseException 
     */
    public int totalSalgEUROVedKasse(Kasse kasse, boolean dankort) throws SQLException, ParseException {
        int beholdningEURO = 0;
        ArrayList<Salg> salgsListe = kasseHandler.hentAlleSalgVedKasse(kasse);
        for (int i = 0; i < salgsListe.size(); i++) {
            Salg salg = salgsListe.get(i);
            if (dankort == salg.isDankort()) {
                if (!salg.isValutaDKK()) {
                    beholdningEURO = beholdningEURO + salg.getTotalBeløb();
                }
            }
        }
        return beholdningEURO;
    }

    /**
     * Returnerer det kasse objekt med pågældende dato
     * @param cal
     * @return
     * @throws SQLException
     * @throws ParseException 
     */
    public Kasse hentKasseVedDato(Calendar cal) throws SQLException, ParseException {
        Kasse valgtKasse = kasseHandler.getKasseVedDato(cal);
        return valgtKasse;
    }

    /**
     * Returnerer alle VareSalg oprettet på det pågældende Kasse objekt. Ved at gennemløbe en ArrayListe af Salgsobjekter
     * tilføjes hvert varesalg til en VaresalgsListe som returneres.
     * @param kasse
     * @return
     * @throws SQLException
     * @throws ParseException 
     */
    public ArrayList<VareSalg> hentAlleVareSalgVedKasse(Kasse kasse) throws SQLException, ParseException {
        ArrayList<Salg> salgsListe = kasseHandler.hentAlleSalgVedKasse(kasse);
        ArrayList<VareSalg> vareSalgsListe = null;
        VareSalg vareSalg;

        for (int i = 0; i < salgsListe.size(); i++) {
            vareSalg = salgsListe.get(i).getVareSalgsListe().get(i);
            vareSalgsListe.add(vareSalg);
        }
        return vareSalgsListe;

    }

    /**
     * Returnerer alle BilletSalg oprettet på det pågældende Kasse objekt. Ved at gennemløbe en ArrayListe af Salgsobjekter
     * tilføjes hvert Billetsalg til en BilletsalgsListe som returneres.
     * @param kasse
     * @return
     * @throws SQLException
     * @throws ParseException 
     */
    public ArrayList<BilletSalg> hentAlleBilletSalgVedKasse(Kasse kasse) throws SQLException, ParseException {
        ArrayList<Salg> salgsListe = kasseHandler.hentAlleSalgVedKasse(kasse);
        ArrayList<BilletSalg> billetSalgsListe = null;
        BilletSalg billetSalg;

        for (int i = 0; i < salgsListe.size(); i++) {
            billetSalg = salgsListe.get(i).getBilletSalgsListe().get(i);
            billetSalgsListe.add(billetSalg);
        }
        return billetSalgsListe;
    }

    /**
     * Returnerer alle EventSalg oprettet på det pågældende Kasse objekt. Ved at gennemløbe en ArrayListe af Salgsobjekter
     * tilføjes hvert Eventsalg til en EventsalgsListe som returneres.
     * @param kasse
     * @return
     * @throws SQLException
     * @throws ParseException 
     */
    public ArrayList<EventSalg> hentAlleEventSalgVedKasse(Kasse kasse) throws SQLException, ParseException {
        ArrayList<Salg> salgsListe = kasseHandler.hentAlleSalgVedKasse(kasse);
        ArrayList<EventSalg> eventSalgsListe = null;
        EventSalg eventSalg;

        for (int i = 0; i < salgsListe.size(); i++) {
            eventSalg = salgsListe.get(i).getEventSalgsListe().get(i);
            eventSalgsListe.add(eventSalg);
        }
        return eventSalgsListe;
    }
    
    public void lukKasse(int slutBeholdningDKK, int slutBeholdningEURO) throws SQLException{
        aktivKasse.setSlutBeholdningDKK(slutBeholdningDKK);
        aktivKasse.setSlutBeholdningEURO(slutBeholdningEURO);
        kasseHandler.lukKasse(aktivKasse);
    }
}
